package com.example.onlineeducation.net

import com.example.onlineeducation.data.db.datastore.UserInfoDataStoreKey
import com.example.onlineeducation.ui.auth.LoginActivity
import com.yc.jetpacklib.exception.YcIoException
import com.yc.jetpacklib.extension.get
import com.yc.jetpacklib.extension.ycLogDSimple
import com.yc.jetpacklib.extension.ycLogESimple
import com.yc.jetpacklib.manager.YcActivityManager
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Response
import okhttp3.ResponseBody
import okio.BufferedSource
import java.io.IOException
import java.nio.charset.Charset
import java.nio.charset.UnsupportedCharsetException

/**
 * SimpleDes:
 * Creator: Sindi
 * Date: 2022-04-01
 * UseDes:
 */
class CookieIntercept : Interceptor {
    companion object {
        private const val KEY_TOKEN_EXPIRATION = "Token失效"
        private const val KEY_TOKEN = "X-Access-Token"
    }

    private val UTF8 = Charset.forName("UTF-8")

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val originReq = chain.request()
        if (YcActivityManager.getCurrentActivity() !is LoginActivity) {
            val builder = originReq.newBuilder().apply {
                runBlocking {
                    val token = UserInfoDataStoreKey.KEY_USER_TOKEN.get()
                    ycLogDSimple("本地token:$token")
                    addHeader(KEY_TOKEN, token)
                }
            }.build()

            val response = chain.proceed(builder)
            if (response.code == 500 && isHasTokenExpiration(response) && YcActivityManager.getCurrentActivity() !is LoginActivity) {
                throw YcIoException(KEY_TOKEN_EXPIRATION, NetCode.NET_CODE_TOKEN_INVALID)
            }
            return response
        } else {
            return chain.proceed(originReq)
        }
    }

    /**
     * 判断是否含有token过期的信息（服务端框架原因，只能这样判断。。。。）
     * @param response Response
     * @return Boolean
     */
    private fun isHasTokenExpiration(response: Response): Boolean {
        return getFullResponse(response)?.contains(KEY_TOKEN_EXPIRATION) == true
    }

    /**
     * 获取到完整的响应数据(服务器返回数据)
     *
     * @param response
     * @return
     */
    private fun getFullResponse(response: Response): String? {
        try {
            val responseBody: ResponseBody? = response.body
            if (responseBody != null) {
                val source: BufferedSource = responseBody.source()
                source.request(Long.MAX_VALUE)
                val buffer = source.buffer
                var charset = UTF8
                val contentType = responseBody.contentType()
                if (contentType != null) {
                    charset = try {
                        contentType.charset(UTF8)
                    } catch (e: UnsupportedCharsetException) {
                        e.printStackTrace()
                        UTF8
                    }
                }
                return buffer.clone().readString(charset)
            } else {
                return null
            }
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }

    }
}